"
" Run svn diff from a file
fun! _SVNDiff(rev)
    let filena = expand("%")
    let revi = a:rev
    if (revi == "")
        let revi = 'BASE'
    endif
    let bufname = expand("%:t") . " Rev. " . revi
    exe ":diffthis"
    exe ":vert new"
    exe ":0r! svn cat -r " . revi . " " . filena
    exe ":diffthis"
    "if for pm pl
    exe ":set syntax=perl"
    nnoremap <buffer> <silent> q    :q!\|diffoff<CR>
    "exe "wincmd w"
    exe "normal gg"
endfun
:command! -nargs=* SVNDiff call _SVNDiff(<q-args>)
"
" Diff based on visual selection
fun! _SVNViDiff()
    let topline = getline("'<")
    let bottomline = getline("'>")
    let revi = matchstr(topline, '^r\zs\d\+\ze')
    let revi2 = matchstr(bottomline, '^r\zs\d\+\ze')
    exe ":silent! tabnew"
    exe ":silent 0r! svn cat -r " . revi . " " . g:filena
    exe ":set syntax=perl"
    exe ":vert new"
    exe ":silent 0r! svn cat -r " . revi2 . " " . g:filena
    exe ":set syntax=perl"
    exe ":diffthis"
    nnoremap <buffer> <silent> q    :q!\|q!<CR>
    exe "wincmd w"
    exe ":diffthis"
    exe "normal gg"
    nnoremap <buffer> <silent> q    :q!\|q!<CR>
endfun
:command! SVNViDiff call _SVNViDiff()

"
" Run svn log from a file
fun! _SVNLog(rev)
    let g:filena = expand("%")
    let revi = a:rev
    if (revi == "")
        let revi = 'BASE:1'
    endif
    exe ":vert new"
    exe ":0r! svn log -r " . revi . " " . g:filena
    exe ":setlocal nonu"
    exe ":set syntax=svnlog"
    nnoremap <buffer> <silent> q    :q!<CR>
    vnoremap <buffer> <silent> df   y:call _SVNViDiff()<CR>
    exe "normal gg"
endfun
:command! -nargs=* SVNLog call _SVNLog(<q-args>)

fun! _SVNRevDiff()
    let line = getline(".")
    let revi = matchstr(line, '^r\zs\d\+\ze')
    "echomsg "Rev is " . revi
    exe ":q!"
    exe ":SVNDiff " . revi
endfun
:command! SVNRevDiff call _SVNRevDiff()

fun! _SVNStatus()
    let status = system("svn st -u ". expand('%'))
    echohl Search
    echomsg status
    echohl None
endfun
:command! SVNStatus call _SVNStatus()

fun! _SVNRevert()
    let status = system("svn revert ". expand('%'))
    exe ":e!"
endfun
:command! SVNRevert call _SVNRevert()

"
" update
fun! _SVNUpdate()
    let update_status = system("svn update ". expand('%'))
    exe ":e!"
    echohl Search
    echomsg update_status
    echohl None
endfun
:command! SVNUpdate call _SVNUpdate()

"
" Run svn commit from a file
fun! _SVNCommit(comment)
    let commit = system("svn ci -m '" . a:comment . "' " . expand('%'))
    echohl Search
    echomsg commit
    echohl None
endfun
:command! -nargs=* SVNCommit call _SVNCommit(<q-args>)

"
" Run svn remove on the current file
fun! _SVNRemove()
    let status = system("svn rm ". expand('%'))
    exe ":bdelete"
    echohl Search
    echomsg status
    echohl None
endfun
:command! SVNRemove call _SVNRemove()

fun! _SVNBrowse(path)
    let g:svnpath = a:path
    if (g:svnpath == "")
        let g:svnpath = 'http://isk-svn.qualcomm.com/repos/core/'
    endif
    exe ":vert new"
    let &titlestring="SVN Browser: ".g:svnpath
    exe ":1r! svn ls " . g:svnpath
    exe ":setlocal nonu"
    nnoremap <buffer> <silent> q    :q!<CR>
    nnoremap <buffer> <silent> <Enter> :call _SVNBrowseUpdate(g:svnpath)<CR>
    nnoremap <buffer> <silent> <BS> :call _SVNBrowseBack(g:svnpath)<CR>
    nnoremap <buffer> <silent> L :call _SVNBrowseLog(g:svnpath)<CR>
endfun
:command! -nargs=* SVNBrowse call _SVNBrowse(<q-args>)

fun! _SVNBrowseUpdate(path)
    let cline = getline(".")
    if (match(cline, '.*\/$') < 0)
        let g:svnpath = a:path."/".cline
        exe "normal ggdG"
        exe ":1r! svn cat " . g:svnpath
    else
        let g:svnpath = a:path.cline
        exe "normal ggdG"
        exe ":1r! svn ls " . g:svnpath
    endif
    let &titlestring="SVN Browser: ".g:svnpath
endfun

fun! _SVNBrowseBack(path)
    let g:svnpath = matchstr(a:path,'\zs.*\/\ze.*\/')
    let location = matchstr(a:path,'.*\/\zs.*\/\ze')
    exe "normal ggdG"
    let &titlestring="SVN Browser: ".g:svnpath
    exe ":1r! svn ls " . g:svnpath
    let match = search(location,"w")
    "echomsg "Ok"
endfun

fun! _SVNBrowseLog(path)
    exe ":new"
    exe ":0r! svn log " . a:path
    exe ":setlocal nonu"
    nnoremap <buffer> <silent> q    :q!<CR>
    vnoremap <buffer> <silent> df   y:call _SVNViDiff()<CR>
    exe "normal gg"
endfun

fun! _SVNDirStatus()
    exe ":new"
    exe ":1r! svn st -u"
    exe ":setlocal nonu"
    nnoremap <buffer> <silent> q    :q!<CR>
endfun
:command! SVNDirStatus call _SVNDirStatus()

augroup svn_blame
  autocmd!
  autocmd BufReadPost *.svnblame setfiletype svnblame
  autocmd FileType svnblame setlocal nomodeline
  "autocmd Syntax fugitiveblame call s:BlameSyntax()
augroup END

function! _SVNBlame()
  try
    let basecmd = "svn blame -v " . expand('%')
    try
        let error = tempname()
        let temp = error.'.svnblame'
        if &shell =~# 'csh'
          silent! execute '%write !('.basecmd.' > '.temp.') >& '.error
        else
          silent! execute '%write !'.basecmd.' > '.temp.' 2> '.error
        endif
        if v:shell_error
          call s:throw(join(readfile(error),"\n"))
        endif
        let bufnr = bufnr('')
        let restore = 'call setwinvar(bufwinnr('.bufnr.'),"&scrollbind",0)'
        if &l:wrap
          let restore .= '|call setwinvar(bufwinnr('.bufnr.'),"&wrap",1)'
        endif
        if &l:foldenable
          let restore .= '|call setwinvar(bufwinnr('.bufnr.'),"&foldenable",1)'
        endif
        let winnr = winnr()
        windo set noscrollbind
        exe winnr.'wincmd w'
        setlocal scrollbind nowrap nofoldenable
        let top = line('w0') + &scrolloff
        let current = line('.')
        exe 'leftabove vsplit '.temp
        let b:fugitive_blamed_bufnr = bufnr
        let w:fugitive_leave = restore
        execute top
        normal! zt
        execute current
        execute "vertical resize ".(match(getline('.'),'('))
        setlocal nomodified nomodifiable nonumber scrollbind nowrap foldcolumn=0 nofoldenable filetype=svnblame
        syncbind
    endtry
    return ''
  catch /^fugitive:/
    return 'echoerr v:errmsg'
  endtry
endfunction
:command! SVNBlame call _SVNBlame()
